package model.trader.trade;


import java.util.ArrayList;

import model.market.MarketInformation;
import model.market.MarketManager;
import model.market.Position;
import model.market.Trade;
import model.trader.TradeInstruction;
import model.trader.Trader;
import model.trader.portfolio.LiquidityMeasure;
/**
 * 
 * @author andy
 *
 * AM: This breaks a large trade and will fill a portion at the market rate, and another portion within a limit price
 * that depends on the aggression of the trader. the further the hold price is from the current market price, the more
 * aggressive the trader can be.
 * 
 * AMLOW: think about the logic in this class.. why do we have two strategies?
 *
 */
public class LiquidityAdjustingExecutionStrategy implements TradeExecutionStrategy{

	private LiquidityMeasure liquid= new LiquidityMeasure();
	private static final int MAX_LIQUID_SHIFT_PERCENTAGE = 1;
	
	public java.util.List<Trade> trade(Trader trader,Position pos,
			TradeInstruction[] tradersInstructions, 
			MarketManager market,MarketInformation marketInfo) {
		
		java.util.List<Trade> ret = new ArrayList<Trade>();
		
		for(TradeInstruction tradeInstruction:tradersInstructions){
			double averageLiquidity = liquid.getTradeValueForOnePercentExpectedShift(
					tradeInstruction.getAsset(),market, marketInfo);
			
			//AM: convert to number of stocks to trade:
			averageLiquidity/=marketInfo.getMarketPrices()[tradeInstruction.getAsset()];
			int numberToTrade = tradeInstruction.getNumberToTrade();
			if(averageLiquidity*MAX_LIQUID_SHIFT_PERCENTAGE<numberToTrade){
				numberToTrade=(int)(averageLiquidity*MAX_LIQUID_SHIFT_PERCENTAGE);
			}
			//GEt the sales as well...
			if(-averageLiquidity*MAX_LIQUID_SHIFT_PERCENTAGE>numberToTrade){
				numberToTrade=-(int)(averageLiquidity*MAX_LIQUID_SHIFT_PERCENTAGE);
			}
			
			Trade marketTrade = new Trade(trader,tradeInstruction.getAsset(),
											numberToTrade,tradeInstruction.getHoldPrice());
			
			if(tradeInstruction.getAsset()==0){
				System.out.println("Market order: "+marketTrade);
			}
			//market.order(marketTrade);
			ret.add(marketTrade);
			
			int remainingTrade = tradeInstruction.getNumberToTrade()-numberToTrade;
			
			
			double spread =tradeInstruction.getHoldPrice()-marketInfo.getMarketPrices()[tradeInstruction.getAsset()];
			Trade trade=new Trade(trader,
					tradeInstruction.getAsset(),
					remainingTrade,
					spread*.2
					+marketInfo.getMarketPrices()[tradeInstruction.getAsset()]);
			//market.order(trade);
			ret.add(trade);
			
		}
		return ret;
	}

}
